import { spawn } from 'child_process';
import { existsSync, readFileSync, writeFileSync } from 'fs-extra';
import { platform } from 'os';
import path, { join } from 'path';
import { createApp, App } from 'vue';
import Electron from 'electron';
const panelDataMap = new WeakMap<any, App>();
const localPath = join(Editor.Project.path, "profiles/tmpl-generator.json");
const tsOutPath = join(Editor.Project.path, "assets/scripts/game/ui")
/**
 * @zh 如果希望兼容 3.3 之前的版本可以使用下方的代码
 * @en You can add the code below if you want compatibility with versions prior to 3.3
 */
// Editor.Panel.define = Editor.Panel.define || function(options: any) { return options }
module.exports = Editor.Panel.define({
    listeners: {
        show() { console.log('show'); },
        hide() { console.log('hide'); },
    },
    template: readFileSync(join(__dirname, '../../../static/template/default/index.html'), 'utf-8'),
    style: readFileSync(join(__dirname, '../../../static/style/default/index.css'), 'utf-8'),
    $: {
        app: '#app',
        text: '#text',
    },
    methods: {
        hello() {
            if (this.$.text) {
                this.$.text.innerHTML = 'hello';
                console.log('[cocos-panel-html.default]: hello');
            }
        },
    },
    ready() {
        if (this.$.app) {
            const app = createApp({});
            app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('ui-');
            app.component('MyCounter', {
                template: readFileSync(join(__dirname, '../../../static/template/vue/counter.html'), 'utf-8'),
                data() {
                    return {
                        moduleName: "",
                        tmplPath: join(__dirname, "../../../bin/core/tmpl"),
                        tsOutPath: tsOutPath,

                        log: "",
                    };
                },
                created() {
                    this.readConfig()
                },
                methods: {
                    logScrollToBottom() {
                        setTimeout(() => {
                            const logElement = this.$refs.logTextArea
                            logElement.scrollTop = logElement.scrollHeight
                        }, 10);
                    },
                    saveConfig() {
                        const data = {
                            moduleName: this.moduleName,
                        }
                        const dataStr = JSON.stringify(data);
                        writeFileSync(localPath, dataStr)
                    },

                    readConfig() {
                        if (existsSync(localPath)) {
                            const buf = readFileSync(localPath, 'utf-8')
                            const data = JSON.parse(buf.toString())
                            if (data) {
                                this.moduleName = data.moduleName || ""
                                // Object.assign(this, data)
                            }
                        }
                    },

                    async selectPath(title: string, defaultPath: string) {
                        if (!existsSync(defaultPath)) {
                            defaultPath = Editor.Project.path
                        }
                        const res = await Editor.Dialog.select({
                            title,
                            path: defaultPath,
                            type: 'directory'
                        })
                        return res.filePaths ? res.filePaths[0] : "";
                    },

                    openPath(path: string) {
                        if (existsSync(path)) {
                            Electron.shell.showItemInFolder(path)
                        } else {
                            console.log("打开路径失败", path)
                        }
                    },

                    async onSelectModuleName() {
                        const path = await this.selectPath("选择excel目录", this.moduleName);
                        if (path) {
                            this.moduleName = path
                            this.saveConfig()
                        }
                    },
                    onOpenModuleName() {
                        this.openPath(this.moduleName)
                    },

                    onModuleNameEdit(e: any) {
                        this.moduleName = e.target.value;
                        this.saveConfig()
                    },

                    async onSelectTmplPath() {
                        const path = await this.selectPath("选择json导出目录", this.tmplPath);
                        if (path) {
                            this.tmplPath = path
                            this.saveConfig()
                        }
                    },
                    onOpenTmplPath() {
                        this.openPath(this.tmplPath)
                    },

                    async onSelectTsOutPath() {
                        const path = await this.selectPath("选择ts模版导出目录", this.tsOutPath);
                        if (path) {
                            this.tsOutPath = path
                            this.saveConfig()
                        }
                    },
                    onOpenTsOutPath() {
                        this.openPath(this.tsOutPath)
                    },

                    onPrettierCheckBox(e: any) {
                        this.isPrettier = e.target.value
                        this.saveConfig()
                    },

                    onExportClientCheckBox(e: any) {
                        this.isExportClientCheckBox = e.target.value
                        this.saveConfig()
                    },

                    onExportServerCheckBox(e: any) {
                        this.isExportServerCheckBox = e.target.value
                        this.saveConfig()
                    },

                    onGenerate() {
                        const cmdParams = []
                        cmdParams.push(`-moduleName=${this.moduleName}`)
                        cmdParams.push(`-src=${this.tmplPath}`)
                        cmdParams.push(`-out=${this.tsOutPath}`)
                        //  `-excel_in=${this.moduleName} -json_out=${this.tmplPath} -t=cs -prettier=${this.isPrettier ? "1" : ""} -tmpl=${this.tsOutPath}`
                        const execuableFileName = platform() == "win32" ? "main.exe" : "main"

                        const bin = path.join(__dirname, `../../../bin/${execuableFileName}`)
                        const childProcess = spawn(bin, cmdParams, { stdio: 'pipe' })
                        this.log = cmdParams.toString() + "\n"
                        childProcess.stdout.on(`data`, (data: any) => {
                            this.log += data
                        });
                        childProcess.stderr.on(`data`, (data) => {
                            this.log += data
                        });
                        childProcess.on(`close`, (data) => {
                            // this.refleshPath(this.tmplPath)
                            this.refleshPath(join(this.tsOutPath, this.moduleName))
                            this.logScrollToBottom();
                            // logScrollToBottom()
                        });
                    },
                    cleanLog() {
                        this.log = ""
                    },
                    refleshPath(path: string) {
                        const dbPath = `db://assets${path.split("assets")[1]}`
                        // Editor.Message.request('asset-db', 'reimport-asset', dbPath);
                        Editor.Message.request('asset-db', 'refresh-asset', dbPath);
                    }
                },
            });
            app.mount(this.$.app);
            panelDataMap.set(this, app);
        }
    },
    beforeClose() { },
    close() {
        const app = panelDataMap.get(this);
        if (app) {
            app.unmount();
        }
    },
});
